package edu.rmit.client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListModel;

import edu.rmit.domain.User;
import edu.rmit.service.IUserService;
import edu.rmit.util.PromotDialog;

/**
 * This panel is used to display the suspend user panel and the corresponding
 * control
 * 
 * @author Joey George
 * @version 1.0
 */
public class SuspendUserPanel {
	/**
	 * The window initialize height.
	 */
	private static int HEIGHT = 500;

	/**
	 * The window initialize width.
	 */
	private static int WIDTH = 480;

	/**
	 * The frame object to initialize the window.
	 */
	private JFrame frame;

	/**
	 * The label which display the currently active users.
	 */
	private JLabel labelActiveUsers;

	/**
	 * The label which display the currently inactive users.
	 */
	private JLabel labelInActiveUsers;

	/**
	 * The list which list the currently active user list.
	 */
	private JList listActiveUsers;

	/**
	 * The list which list the currently inactive user list.
	 */
	private JList listInActiveUsers;

	/**
	 * The button which which clicked will cause the current user is been
	 * suspended.
	 */
	private JButton buttonSuspend;

	/**
	 * The button which clicked will restore a user.
	 */
	private JButton buttonRestore;

	/**
	 * The client instance which can get the corresponding RMI servie from it.
	 */
	private Client client;

	/**
	 * A list of active users.
	 */
	private List<User> activeUsers;

	/**
	 * A list of inactive users.
	 */
	private List<User> inActiveUsers;

	/**
	 * The constructor is to inialize the panel and the coresponding control.
	 * 
	 * @param client
	 *            The instance which can get service from RMI service
	 */
	public SuspendUserPanel(Client client) {
		this.client = client;
		labelActiveUsers = new JLabel("Active Users:");
		labelInActiveUsers = new JLabel("Suspended Users:");
		buttonSuspend = new JButton("Suspend this user ==>");
		buttonSuspend.addActionListener(new ListenerSuspendUser());
		buttonRestore = new JButton("<==Restore this user");
		buttonRestore.addActionListener(new ListenerRestoreUser());

		IUserService userService = client.getUserService();
		try {
			activeUsers = userService.getUsersByActiveStatus(true);
			inActiveUsers = userService.getUsersByActiveStatus(false);
		} catch (RemoteException e) {
			e.printStackTrace();
		}

		listActiveUsers = new JList(getNameList(activeUsers));
		listActiveUsers.setBackground(Color.gray);
		listInActiveUsers = new JList(getNameList(inActiveUsers));
		listInActiveUsers.setBackground(Color.gray);

		JPanel panelActiveUsers = new JPanel();
		panelActiveUsers.setLayout(new BorderLayout());
		panelActiveUsers.add(labelActiveUsers, BorderLayout.NORTH);
		panelActiveUsers.add(listActiveUsers, BorderLayout.CENTER);

		JPanel panelMoveOperations = new JPanel();
		panelMoveOperations.setLayout(new GridLayout(3, 1));
		panelMoveOperations.add(new JLabel(""));
		JPanel panelButtons = new JPanel();
		panelButtons.setLayout(new GridLayout(3, 1));
		panelButtons.add(buttonSuspend);
		panelButtons.add(new JLabel(""));
		panelButtons.add(buttonRestore);
		panelMoveOperations.add(panelButtons);

		JPanel panelInActiveUsers = new JPanel();
		panelInActiveUsers.setLayout(new BorderLayout());
		panelInActiveUsers.add(labelInActiveUsers, BorderLayout.NORTH);
		panelInActiveUsers.add(listInActiveUsers, BorderLayout.CENTER);

		JPanel panelWhole = new JPanel();
		panelWhole.setLayout(new GridLayout(1, 3));
		panelWhole.add(panelActiveUsers);
		panelWhole.add(panelMoveOperations);
		panelWhole.add(panelInActiveUsers);
		panelWhole.setBorder(BorderFactory.createTitledBorder("Users"));

		frame = new JFrame("Suspend and Restore Users");
		frame.setContentPane(panelWhole);
		initFrame();
	}
	
	/**
	 * This method is to 
	 * @param users
	 * @return
	 */
	private String[] getNameList(List<User> users) {
		String[] names = new String[users.size()];
		for (int i = 0; i < users.size(); i++) {
			names[i] = users.get(i).getUserName();
		}
		return names;
	}

	private void initFrame() {
		frame.setResizable(true);
		frame.setVisible(true);
		frame.setSize(WIDTH, HEIGHT);

		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		Dimension frameSize = frame.getSize();
		if (frameSize.height > screenSize.height) {
			frameSize.height = screenSize.height;
		}
		if (frameSize.width > screenSize.width) {
			frameSize.width = screenSize.width;
		}
		frame.setLocation((screenSize.width - frameSize.width) / 2,
				(screenSize.height - frameSize.height) / 2);
	}

	class ListenerSuspendUser implements ActionListener {
		public void actionPerformed(ActionEvent event) {
			int index = listActiveUsers.getSelectedIndex();
			if (index != -1) {
				moveUser(activeUsers, inActiveUsers, listActiveUsers,
						listInActiveUsers, false);
			} else {
				PromotDialog.errorMessageBox(null, "Operation error",
						"Please select an active user first.");
				return;
			}
		}
	}

	class ListenerRestoreUser implements ActionListener {
		public void actionPerformed(ActionEvent event) {
			int index = listInActiveUsers.getSelectedIndex();
			if (index != -1) {
				moveUser(inActiveUsers, activeUsers, listInActiveUsers,
						listActiveUsers, true);
			} else {
				PromotDialog.errorMessageBox(null, "Operation error",
						"Please select a suspended user first.");
				return;
			}
		}
	}

	private void moveUser(List<User> fromUserList, List<User> toUserList,
			JList fromJList, JList toJList, boolean statusToChangeInto) {
		int index = fromJList.getSelectedIndex();
		User selectedUser = fromUserList.get(index);
		try {
			client.getUserService().changeActiveStatus(
					selectedUser.getUserName(), statusToChangeInto);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		toUserList.add(fromUserList.get(index));
		fromUserList.remove(index);

		DefaultListModel listModel = new DefaultListModel();
		ListModel currentListModel = fromJList.getModel();
		for (int i = 0; i < currentListModel.getSize(); i++) {
			if (i != index) {
				listModel.addElement(fromJList.getModel().getElementAt(i));
			}
		}
		fromJList.setModel(listModel);

		// Add this user into destination list.
		changeUserList(toJList, toUserList.get(toUserList.size() - 1)
				.getUserName());
	}

	private void changeUserList(JList listUser, String newValue) {
		DefaultListModel listModel = new DefaultListModel();
		ListModel currentListModel = listUser.getModel();
		for (int i = 0; i < currentListModel.getSize(); i++) {
			listModel.addElement(listUser.getModel().getElementAt(i));
		}
		listModel.addElement(newValue);
		listUser.setModel(listModel);
	}

	public static void main(String[] args) {
		Client client = new Client("127.0.0.1", 1099);
		client.lookUpService();
		new SuspendUserPanel(client);
	}

}
